1 module hip.gui.button; 2 import hip.api.graphics.g2d.renderer2d; 3 public import hip.gui.widget; 4 5 6 interface IButtonRenderer 7 { 8 void render(Widget.Bounds worldBounds, Button.State state); 9 static IButtonRenderer DebugButtonRenderer() 10 { 11 __gshared IButtonRenderer dbgRenderer; 12 if(dbgRenderer is null) 13 { 14 dbgRenderer = new class IButtonRenderer 15 { 16 void render(Widget.Bounds worldBounds, Button.State state) const 17 { 18 alias b = worldBounds; 19 final switch(state) with(Button.State) 20 { 21 case idle: fillRoundRect(b.x, b.y, b.width, b.height, 12, HipColor.red); 22 break; 23 case hovered: fillRoundRect(b.x, b.y, b.width, b.height, 12, HipColor(255, 127, 0)); 24 break; 25 case pressed: fillRoundRect(b.x, b.y, b.width, b.height, 12, HipColor(127, 0, 0)); 26 break; 27 } 28 } 29 }; 30 } 31 return dbgRenderer; 32 } 33 } 34 35 class SpriteButtonRenderer : IButtonRenderer 36 { 37 IHipTextureRegion idle; 38 IHipTextureRegion hover; 39 IHipTextureRegion pressed; 40 41 42 void render(Widget.Bounds worldBounds, Button.State state) 43 { 44 IHipTextureRegion target; 45 final switch ( state ) 46 { 47 case Button.state.idle: target = idle; break; 48 case Button.state.hovered: target = hover; break; 49 case Button.state.pressed: target = pressed; break; 50 } 51 drawRegion(target, worldBounds.x, worldBounds.y); 52 } 53 } 54 55 class Button : Widget 56 { 57 enum State 58 { 59 idle, 60 pressed, 61 hovered, 62 } 63 64 State state; 65 IButtonRenderer renderer; 66 67 protected void delegate() onClick; 68 protected void delegate() onHover; 69 70 this(int x, int y, int w, int h) 71 { 72 setPosition(x,y); 73 width = w; 74 height = h; 75 renderer = IButtonRenderer.DebugButtonRenderer; 76 } 77 void setOnHover(void delegate() onHover) 78 { 79 this.onHover = onHover; 80 } 81 void setOnClick(void delegate() onClick) 82 { 83 this.onClick = onClick; 84 } 85 86 private bool isMouseInsideButton() 87 { 88 import hip.api; 89 import hip.math.collision; 90 Bounds b = getWorldBounds(); 91 float[2] pos = HipInput.getMousePosition(); 92 return isPointInRect(pos[0], pos[1], b.x, b.y, b.width, b.height); 93 } 94 95 override void onMouseEnter() 96 { 97 if(onHover) onHover(); 98 state = State.hovered; 99 } 100 override void onMouseDown() 101 { 102 state = State.pressed; 103 } 104 override void onMouseUp() 105 { 106 if(state == State.pressed && onClick) onClick(); 107 state = State.idle; 108 } 109 override void onMouseExit() 110 { 111 if(state != State.pressed) 112 state = State.idle; 113 } 114 115 void setButtonRenderer(IButtonRenderer renderer) 116 { 117 this.renderer = renderer; 118 } 119 override void onRender() 120 { 121 import hip.api; 122 renderer.render(Bounds(worldTransform.x, worldTransform.y, width, height), state); 123 } 124 }